<?php
/**
 * sait-mailer v0.1
 * 
 * Описание: MODx сниппет рассылающий информацию об изменение на сайте зарегистрированным web пользователям. 
 * Автор:    Карпенко Алексей, tonatos@mail.ru
 * Дата:     10.12.2008 
**/

class c_site_mailer {

	protected $prefix;
	protected $path;
	protected $id;
	protected $config;
	
	public  $message;
	
	function c_site_mailer(){
		global $modx;
		$this->id = $_REQUEST['id'];
		$this->prefix = $modx->db->config['table_prefix'];
		$this->path   = strtr(realpath(dirname(__FILE__)), '\\', '/');
		if (!class_exists('CChunkie')) include_once($this->path . '/includes/chunkie.class.inc.php');
		$this->check_install();
	}

	protected function send_mail($email, $subject, $body){
		global $modx;
		include_once $modx->config['base_path']."manager/includes/controls/class.phpmailer.php";
		
		$mail = new PHPMailer();
		$mail->IsMail();
		$mail->IsHTML(true);
		$mail->CharSet   = "UTF-8";
		$mail->From      = $modx->config['emailsender'];
		$mail->FromName  = $modx->config['site_name'];
		$mail->Subject   = $subject;
		$mail->Body      = $body;
		$mail->AddAddress($email);
		if (!$mail->Send()){
			print($mail->ErrorInfo);
		}
	}
	
	protected function check_install(){
		global $modx;
		$prefix = $this->prefix;		
		
		$sql = "SHOW TABLES LIKE '{$prefix}site_mailer'";
		$rs = $modx->db->query($sql);
		$count = $modx->db->getRecordCount($rs);
		if($count < 1) {		
			$sql = "CREATE TABLE `{$prefix}site_mailer` (`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, `doc_id` INT NOT NULL, `status` INT NOT NULL, `time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, INDEX (`doc_id`, `status`) )";
			$modx->db->query($sql);
			$this->message = "Установка прошла успешно";	
		}

		$sql = "SHOW TABLES LIKE '{$prefix}site_mailer_config'";
		$rs = $modx->db->query($sql);
		$count = $modx->db->getRecordCount($rs);
		if($count < 1) {		
			$sql = "CREATE TABLE `{$prefix}site_mailer_config` (`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, `id_type` INT NOT NULL, `name` VARCHAR(255) NOT NULL, `value` VARCHAR(255) NOT NULL, INDEX (`id_type`) )";
			$modx->db->query($sql);			
			$modx->db->query("insert into `{$prefix}site_mailer_config` (id,id_type,name,value) values (1, 0,'Отправлять скрытые в меню','0');");
			$modx->db->query("insert into `{$prefix}site_mailer_config` (id,id_type,name,value) values (2, 0,'Время &quot;выдержки&quot; документов','15');");
			$modx->db->query("insert into `{$prefix}site_mailer_config` (id,id_type,name,value) values (3, 0,'Рассылать изменения документов','0');");
			$modx->db->query("insert into `{$prefix}site_mailer_config` (id,id_type,name,value) values (4, 0,'ID документа управляющего подпиской','0');");
			$modx->db->query("insert into `{$prefix}site_mailer_config` (id,id_type,name,value) values (5, 0,'Управление подпиской на форум (если установлен Vanilla 1.1.5 + Notifi 1.8)','0');");

			$modx->db->query("alter table `{$prefix}web_user_attributes` add `subscribes` VARCHAR(255) NOT NULL DEFAULT 'all'");

			$this->message = "Установка прошла успешно";	
		}
		
		$rs = $modx->db->query("SHOW TABLES LIKE 'lum_Notifi'");
		$count = $modx->db->getRecordCount($rs);
		$this->vanilla = ($count == 1);
		
	}
	
	
	/**
	 * Получение новые документы на сайте
	 *
	 */
	protected function get_new_doc(){
		global $modx;

		$sql = "select doc_id from `{$this->prefix}site_mailer` where `status` = 0 and `time` < DATE_SUB(NOW(), INTERVAL {$this->config[2]['value']} MINUTE) group by doc_id"; 
		$rs = $modx->db->query($sql);
		
		$created_ids = array();
		while ($row=$modx->db->GetRow($rs)){
			$created_ids[$row['doc_id']] = $row['doc_id'];
		}
		
		return empty($created_ids)?false:$created_ids;
	}


	/**
	 * Выбираем id измененных документов
	 *
	 */
	protected function get_updated_ids(){
		global $modx;

		if ($this->config[3]['value']=='0') return false;
		
		$sql = "select doc_id from `{$this->prefix}site_mailer` where `status` = 1 and `time` < DATE_SUB(NOW(), INTERVAL {$this->config[2]['value']} MINUTE) group by doc_id"; 
		$rs = $modx->db->query($sql);
		$updated_ids = array();
		while ($row=$modx->db->GetRow($rs)){
			$updated_ids[$row['doc_id']] = $row['doc_id'];
		}
		return empty($updated_ids)?false:$updated_ids;
	}
	
	public function cron($debug = false, $send = true){
		global $modx;		
		
		$this->load_config();		

		$created_ids = $this->get_new_doc();		

		$updated_ids = $this->get_updated_ids();		

		if ($debug) $result  = "<p><strong>site_mailer cron debug:</strong></p>";
		if ($debug) $result .= "<p>minute: {$this->config[2]['value']}</p>";
		if ($debug) $result .= "<p>created_ids: ".(@implode(",",$created_ids))."</p>";
		if ($debug) $result .= "<p>updated_ids: ".(@implode(",",$updated_ids))."</p>";
		
		//Нет данных
		if (($created_ids===false)&&($updated_ids===false)) return $result;

		//Исключаем одинаковые документы из массива новых и измененных, чтобы избежать повторения
		if (($created_ids!==false)&&($updated_ids!==false)){
			$updated_ids = array_diff($updated_ids,$created_ids);
		}
		
		//Получаем список пользователей
		$users = array();
		$rs = $modx->db->query("select wa.fullname, wa.email, wa.subscribes, wu.username from {$this->prefix}web_user_attributes wa, {$this->prefix}web_users wu where wu.id=wa.internalKey and wa.subscribes!='' order by wu.id");
		while ($row = $modx->db->GetRow($rs)){
			$row['fullname'] = empty($row['fullname']) ? $row['username'] : $row['fullname'];
			$users[] = $row;
		}
		
		
		if ($debug) $result .= "<p>users: <pre>".(print_r($users,true))."</pre></p>";

		//Массивы отправленных документов 
		$sendind_created = array();
		$sendind_updated = array();
		
		//Формируем основную часть письма
		$body="";
		
		if ($created_ids!==false){
			
			$where = "id in (".implode(",",$created_ids).") and published=1";
			if ($this->config[1]['value']=='0'){
				$where .= " and hidemenu = 0";
			}
			
			$created = $modx->getIntTableRows("id, pagetitle, createdon", "site_content", $where, "createdon");
			if (!empty($created)){
				$body = "<p>Новые документы на сайте &quot;".$modx->config['site_name']."&quot;</p><ul>";

				foreach ($created as $row){
					$body .= "<li><a href='".$modx->config['site_url'].$modx->makeUrl($row['id'])."'>".$row['pagetitle']."</a></li>";
					$sendind_created[]=$row['id'];
				}
				$body.="</ul>";
			}
		}
		
		if ($updated_ids!==false){

			$where = "id in (".implode(",",$updated_ids).") and published=1";
			if ($this->config[1]['value']=='0'){
				$where .= " and hidemenu = 0";
			}

			$updated = $modx->getIntTableRows("id, pagetitle, editedon", "site_content",$where, "editedon");
			if (!empty($updated)){
				$body .= "<p>Измененные документы на сайте &quot;".$modx->config['site_name']."&quot;</p><ul>";

				foreach ($updated as $row){
					$body .= "<li><a href='".$modx->config['site_url'].$modx->makeUrl($row['id'])."'>".$row['pagetitle']."</a></li>";
					$sendind_updated[]=$row['id'];
				}
				$body.="</ul>";
			}				
		}

		if (empty($body)) return;
		
		$body = str_replace($modx->config['site_url']."/",$modx->config['site_url'],$body);
		
		if ($debug) $result .= "<p>body: <pre>$body</pre></p>";
		
		
		
		//Удаляем документы из таблицы в независимости от их физичесой отправки
		//Сначала удаляем из базы а потом отправляем, так как при большом кол-ве подписчиков
		//время соединения может быть утрачено в процессе рассылки
		$del_ids = array_merge($sendind_created, $sendind_updated);
        if (($send)&&(!empty($del_ids))) $modx->db->query("delete from {$this->prefix}site_mailer where doc_id in (".implode(",",$del_ids).")");

        if (empty($users)) return "";

        $site_url = "<a href='".$modx->config['site_url']."'>".$modx->config['site_name']."</a>";
        $subscribe_url = $modx->config['site_url'].$modx->makeUrl($this->config[4]['value']);
        $subscribe_url = "<a href='$subscribe_url'>$subscribe_url</a>";

		//Чанки были заменены на str_replace из-за того что при большом объему замен "умные" чанки 
		//думали что вошли в бесконечный цикл и неработали		
        $tpl = file_get_contents($this->path."/templates/snippet_mail_send.tpl");
		$tpl = str_replace("[+site_url+]",$site_url,$tpl);
		$tpl = str_replace("[+subscribe_url+]",$subscribe_url,$tpl);
		$tpl = str_replace("[+body+]",$body, $tpl);		
		
        //Рассылаем письма
		foreach ($users as $user){
		
			$mail_body = str_replace("[+fullname+]",$user['fullname'], $tpl);

            if ($send) {
            	$this->send_mail($user['email'], "Изменения на сайте ".$modx->config['site_name'],$mail_body);
            //}else{
            //	$this->send_mail("tonatos@mail.ru", "Изменения на сайте ".$modx->config['site_name'],$mail_body);
            }
        }
        
        return $result;
	}
	
	public function execute_module(){
		global $modx;
		
		if ($modx->isFrontend()) return "";
		
		$output = file_get_contents($this->path."/templates/execute_module.tpl");
		
		$action = $_REQUEST['action'];

		$content = (!empty($action))? $this->$action() : $this->module_main();
			
		$output = str_replace(array("[+content+]","[+id+]","[+message+]"),array($content,$this->id,$this->message),$output);

		return $output;
		
	}
	
	protected function load_config(){
		global $modx;
		$this->config = array();
		
		foreach ($modx->getIntTableRows("id,name,value","site_mailer_config","id_type=0","id") as $row){
			$this->config[$row['id']] = $row;				
		}		
	}
	
	protected function module_main(){
		global $modx;
				
		if (!empty($_POST)){
			$modx->db->query("update {$this->prefix}site_mailer_config set value = ".( empty($_POST[1]) ? 0 : 1 )." where id=1");
			$modx->db->query("update {$this->prefix}site_mailer_config set value = ".((int)$_POST[2])." where id=2");
			$modx->db->query("update {$this->prefix}site_mailer_config set value = ".( empty($_POST[3]) ? 0 : 1 )." where id=3");
			$modx->db->query("update {$this->prefix}site_mailer_config set value = ".((int)$_POST[4])." where id=4");
			$modx->db->query("update {$this->prefix}site_mailer_config set value = ".( empty($_POST[5]) ? 0 : 1 )." where id=5");
		}
		
		$this->load_config();

		$tpl = new CChunkie($this->path."/templates/module_main.tpl");
		$tpl->AddVar('id',$this->id);
		$tpl->AddVar('config',$this->config);
		$tpl->AddVar('vanilla',$this->vanilla ? " - <span style='color:green'>обнаружено</span>!":" - <span style='color:red'>отсутствует</span>");
		return  $tpl->Render();
	}
	
	protected function module_mail_list(){
		global $modx;
		
		if (!empty($_POST)){
			if (!empty($_POST['new_parent'])){
				if (empty($_POST['name'])){
					
					$doc = $modx->GetDocument($_POST['new_parent']);
					$_POST['name'] = $doc['pagetitle'];
					
				}
				$modx->db->query("insert into `{$this->prefix}site_mailer_config` (id_type,name,value) values (1,'".$modx->db->escape($_POST['name'])."','".$modx->db->escape($_POST['new_parent'])."')");
			}
		}
		
		$mail_list = $modx->getIntTableRows("id,name,value","site_mailer_config","id_type=1","id");
		
		foreach($mail_list as $row){
			$list .= "<li>[<a href='?a=112&id=$this->id&action=module_mail_list_delete&m_id={$row['id']}'>X</a>] {$row['name']} ({$row['value']})</li>";
		}
		
		
		$tpl = new CChunkie($this->path."/templates/module_mail_list.tpl");
		$tpl->AddVar('id',$this->id);
		$tpl->AddVar('list',$list);

		return $tpl->Render();
	}
	
	protected function module_mail_list_delete(){
		global $modx;
		if (isset($_GET['m_id'])){
			$modx->db->query("delete from `{$this->prefix}site_mailer_config` where id = ".((int)$_GET['m_id']));
		}
		return $this->module_mail_list();	
	}
	
	public function subscribe(){
		global $modx;
		$uid = $modx->getLoginUserID();
		
		if (!is_numeric($uid)) return "Вы не вошли в систему";
		
		$this->load_config();

		//Интеграция с Vanilla
		if (($this->vanilla) && ($this->config[5]['value']=='1')){
			$result  = $modx->db->query("select NotifiID from lum_Notifi where UserID = '$uid' AND Method = 'ALL'");
			$vanilla = $modx->db->GetRow($result);
			
			if (!empty($vanilla)) $vanilla = "checked";

		}
		
		
		if ($_POST['action']=="subscribe_commit"){

			$mail_list = empty($_POST['mail_list']) ? "" : implode(",", $_POST['mail_list']);
			$modx->db->query("update {$this->prefix}web_user_attributes set subscribes = '$mail_list' where internalkey = $uid");

			//Интеграция с Vanilla
			if (($this->vanilla) && ($this->config[5]['value']=='1')){
				if (empty($_POST['vanilla'])){
					$modx->db->query("delete from lum_Notifi where UserID = '$uid' AND Method = 'ALL'");
					$vanilla = "";
				}else{
					if (empty($vanilla)){
						$modx->db->query("insert into lum_Notifi (UserID, Method,SelectID) values ('$uid','ALL',0)");
						$vanilla = "checked";
					}
				}
			}

		}
		
		$udata = $modx->getWebUserInfo($uid);
		$mail_list = explode(",",$udata['subscribes']);

	
		$tpl = new CChunkie($this->path."/templates/snippet_mail_list.tpl");
		$tpl->AddVar('mail_list',$mail_list);
		$tpl->AddVar('action',$modx->makeUrl($modx->documentIdentifier));
		$tpl->AddVar('config',$this->config);
		$tpl->AddVar('vanilla',$vanilla);

		return $tpl->Render();
	}
	
	public function module_cron(){
		return $this->cron(true, false);
	}
	
	public function module_userlist(){
		global $modx;
		$result = "<table border=1 class='black'>";
		//Получаем список пользователей
		$users = array(); 
		$rs = $modx->db->query("select wa.fullname, wa.email, wa.subscribes, wu.username from {$this->prefix}web_user_attributes wa, {$this->prefix}web_users wu where wu.id=wa.internalKey order by wu.id");
		while ($row = $modx->db->GetRow($rs)){
			$result .= "<tr><td>".$row['fullname']."</td><td>".$row['email']."</td><td>".$row['subscribes']."</td><td>".$row['username']."</td></tr>";
		}
		$result.="</table>";
		
		return $result;
	
	}
}

?>